//go:build !windows
// +build !windows

package main

import (
	"log"
	"os"

	"github.com/containerd/containerd/platforms"
	"github.com/moby/buildkit/util/archutil"
)

// https://github.com/qemu/qemu/blob/master/scripts/qemu-binfmt-conf.sh

type config struct {
	binary string
	magic  string
	mask   string
}

var configs = map[string]config{
	"amd64": {
		binary: "qemu-x86_64",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00`,
		mask:   `\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"arm64": {
		binary: "qemu-aarch64",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"arm": {
		binary: "qemu-arm",
		magic:  `\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"s390x": {
		binary: "qemu-s390x",
		magic:  `\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff`,
	},
	"ppc64le": {
		binary: "qemu-ppc64le",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00`,
	},
	"riscv64": {
		binary: "qemu-riscv64",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"386": {
		binary: "qemu-i386",
		magic:  `\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00`,
		mask:   `\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"mips64le": {
		binary: "qemu-mips64el",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
	"mips64": {
		binary: "qemu-mips64",
		magic:  `\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff`,
	},
	"loongarch64": {
		binary: "qemu-loongarch64",
		magic:  `\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01`,
		mask:   `\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff`,
	},
}

func allArch() []string {
	m := map[string]struct{}{}
	for _, pp := range formatPlatforms(archutil.SupportedPlatforms(true)) {
		p, err := platforms.Parse(pp)
		if err == nil {
			m[p.Architecture] = struct{}{}
		} else {
			log.Printf("error: %+v", err)
		}
	}

	out := make([]string, 0, len(configs))
	for name := range configs {
		if _, ok := m[name]; !ok {
			if _, fullPath, err := getBinaryNames(configs[name]); err == nil {
				if _, err := os.Stat(fullPath); err == nil {
					out = append(out, name)
				}
			} else {
				// Make sure install() will print the error
				out = append(out, name)
			}
		}
	}
	return out
}
